import {extend, isDef} from "../../../shared/util";

/**
 * 获取插槽节点子组件作用域实例
 * @param {Object} data
 * @return {{}}
 */
function getSlotScopeInstance (data) {
    const scope = {};
    // 获取所有动态绑定的变量
    if (isDef(data.bindAttrs)) {
        extend(scope, data.bindAttrs);
    }
    // 返回作用域
    return scope;
}

/**
 * 获取插槽节点信息对象
 * @param {String} name
 * @param {Reactive} componentInstance
 * @return {{
 *     name: String,
 *     scopeAlias: String,
 *     renderCode: String,
 *     render: Function
 * }}
 */
function getSlotItem (name, componentInstance) {
    return componentInstance.slots[name];
}

/**
 * 渲染插槽节点
 * @param {String} name 插槽名称
 * @param {Object} data 插槽被绑定数据
 * @return {Array<VNode>|VNode} 渲染好的 VNode 节点
 */
export function renderSlot (name, data) {
    // 获取插槽节点信息
    const slotItem = getSlotItem(name, this);
    // 获取 slot 作用域别名和实例
    const context = {};
    extend(context, this.parentComponent);
    const slotScopeAlias = slotItem.scopeAlias;
    if (slotScopeAlias !== 'undefined') {
        context[slotScopeAlias] = getSlotScopeInstance(data);
    }
    // 渲染插槽节点的 虚拟DOM节点
    // 默认方式
    if (name === 'default') {
        const vnodeList = [];
        for (let i=0; i<slotItem.length; i++) {
            const render = slotItem[i].render;
            // 传入上下文环境变量
            const vnode = render.call(context);
            vnodeList.push(vnode);
        }
        return vnodeList;
    }
    // 具名插槽方式
    else {
        const render = slotItem.render;
        const vnode = render.call(context);
        return vnode;
    }
}
